package com.bottle.service.impl;

import com.bottle.enity.TokenAuth;
import com.bottle.enity.User;
import com.bottle.enity.UserBridge;
import com.bottle.mode.BridgeInfo;
import com.bottle.service.UserService;
import com.bottle.utils.MD5Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: chenyuncong
 * @Date: 2020/4/30 10:49
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ConcurrentHashMap<String,String> userIdCache;

    //经过运算获取到用户自己的在线用户
    @Override
    public Set<String> userOnLineSet(String userId, BridgeInfo bridgeInfo, Set<String> onLineAll){
        //获取桥梁里面用户对应的发送id
        Set<String> userIdSet = new HashSet<>();
        userIdSet.add(userId); //添加到自身的集合
        Set<String> bridgeUserIdSet = new HashSet<>(); //新建一个集合
        bridgeUserIdSet.addAll(bridgeInfo.getUserIds());//用通道的用户，赋值新对象
        bridgeUserIdSet.removeAll(userIdSet); //减去自身的集合

        //
        Set<String> onLineSet = new HashSet<>();
        onLineSet.addAll(onLineAll);//在线用户
        onLineSet.retainAll(bridgeUserIdSet);//在线用户和桥梁集合 的交集，等于 桥梁里在线用户集合
        return onLineSet;
    }

    @Override
    public User getUserByAccount(String account){
        Query query= new Query(Criteria.where("account").is(account)).limit(1);
        return mongoTemplate.findOne(query,User.class);
    }

    //获取最新一条认证
    @Override
    public TokenAuth getTokenAuth(String jwt){
        Query query = new Query(Criteria.where("jwt").is(jwt)).limit(1);
        return mongoTemplate.findOne(query,TokenAuth.class);
    }

    //所有用户ID加密后加进缓存
    @Override
    public void loadAllUserIdToCache(){
        Query query = new Query();
        query.fields().include("_id");
        List<User> list = mongoTemplate.find(query, User.class);
        list.forEach(x->{
            userIdCache.put(MD5Utils.md5_16Encrypt(x.getId()),x.getId());
            //加多一个 userid -> name 缓存
        });
    }

    @Override
    public User getUserById(String userId){
        return mongoTemplate.findById(userId,User.class);
    }

    //添加用户
    @Override
    public User saveUser(User u) {
        u.setPassword(MD5Utils.md5(u.getPassword()));
        u.setCreateTime(System.currentTimeMillis());
        return mongoTemplate.save(u);
    }

    //更新用户数据
    @Override
    public void updateUser(User u){
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(u.getId()));
        Update update = new Update();
        update.set("encrUserId", u.getEncrUserId());
        update.set("account", u.getAccount());
        update.set("password", u.getPassword());
        update.set("name", u.getName());
        update.set("email", u.getEmail());
        update.set("sex", u.getSex());
        update.set("createTime", u.getCreateTime());
        update.set("phone", u.getPhone());
        update.set("isDel", u.getIsDel());
        mongoTemplate.upsert(query, update, "s_user");
    }
    @Override
    public UserBridge addFriend(String encrUserId,String enrcFriendId){
        UserBridge userBridge=new UserBridge();
        String userId = userIdCache.get(encrUserId);
        if(StringUtils.isEmpty(userId)){
            return userBridge;
        }
        String friendId = userIdCache.get(enrcFriendId);
        if(StringUtils.isEmpty(friendId)){
            return userBridge;
        }
        String encryptionId= MD5Utils.compareToEncyPass(userId,friendId);
        userBridge.setType(0); //0位单聊 1位聊天群
        userBridge.setStatus(0); // 0 为不通过 1位通过
        userBridge.setUserId(userId);
        userBridge.setEncryptionId(encryptionId);
        userBridge.setCreateTime(System.currentTimeMillis());
        mongoTemplate.save(userBridge);
        return userBridge;
    }
    //添加用户桥梁（用户关系）
    @Override
    public UserBridge saveUserBridge(UserBridge ub) {
        return mongoTemplate.save(ub);
    }

    //根据账号密码查询是否存在
    @Override
    public User checkUserLogin(String account, String password) {
        Query query = new Query(Criteria.where("account").is(account).and("password").is(password)).limit(1);
        return mongoTemplate.findOne(query, User.class);
    }

    /**
     * 使用 userId 获取对应的桥梁关系
     * @param userId
     * @return
     */
    @Override
    public List<UserBridge> getEncryptionIdsByUserId(String userId) {
        Query query = new Query(Criteria.where("userId").is(userId));
        List<UserBridge> list = mongoTemplate.find(query, UserBridge.class);
        return list;
    }

    //使用 加密关系id 获取 里面对应的用户id
    @Override
    public Set<String> getUserIdByEncryptionId(String encryptionId){
        Query query = new Query(Criteria.where("encryptionId").is(encryptionId));
        query.fields().include("userId");
        List<UserBridge> ubList = mongoTemplate.find(query,UserBridge.class);
        Set<String> list= new HashSet<>();
        ubList.forEach(ub->list.add(MD5Utils.md5_16Encrypt(ub.getUserId())));
        return list;
    }
}
